package com.touchalachs.core.updateThread;

import com.touchalachs.core.GameView;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Point;

/**
 * Nette Idee, funktioniert leider nicht so wie erhofft
 */
@Deprecated
public class UpdateNBufferedDrawThread extends UpdateThread {
	static final int PHYSICS_FPS = 50;
	static final int PHYSICS_MS_PER_FRAME = 1000 / PHYSICS_FPS;
	static final int GRAFICS_FPS = 25;
	static final int GRAFICS_MS_PER_FRAME = 1000 / GRAFICS_FPS;
	private GameView view;
	private boolean running = false;
	private volatile Bitmap framebuffer[] = new Bitmap[3];
	private volatile int drawableBitmap = 0;
	private DrawThread drawThread;

	public UpdateNBufferedDrawThread(GameView view, Point screnSize) {
		this.view = view;
		framebuffer[0] = Bitmap.createBitmap(screnSize.x, screnSize.y, Config.ARGB_4444);
		framebuffer[1] = Bitmap.createBitmap(screnSize.x, screnSize.y, Config.ARGB_4444);
		framebuffer[2] = Bitmap.createBitmap(screnSize.x, screnSize.y, Config.ARGB_4444);
	}

	@Override
	public void setRunning(boolean run) {
		running = run;
	}

	@Override
	public void run() {
		while (running && ( !view.getHolder().getSurface().isValid() || view.getHolder().isCreating())) {
			sleepRemainingFrameTime(50, 0);
		}
		drawThread = new DrawThread();
		drawThread.start();
		long previousStartTime = System.currentTimeMillis();
		long previousDrawTime = 0;
		while (running) {
			long startTime = System.currentTimeMillis();
			float secSinceLastUpdate = (startTime - previousStartTime)/1000f;
			
			view.update(secSinceLastUpdate);
			
			if (startTime-previousDrawTime > GRAFICS_MS_PER_FRAME/2){
				previousDrawTime = startTime;
				int updatingBitmap = (drawableBitmap+1)%3;
				Canvas c = new Canvas(framebuffer[updatingBitmap]);
				view.draw(c);
				drawableBitmap = updatingBitmap;
			}
			
			long endTime = System.currentTimeMillis();
			previousStartTime = startTime;
			
			sleepRemainingFrameTime(PHYSICS_MS_PER_FRAME, endTime-startTime);
		}

	}

	private static void sleepRemainingFrameTime(int desiredDelay, long workTime) {
		long sleepTime = desiredDelay - workTime;
//		System.out.println(Thread.currentThread().getClass().getSimpleName()+" - sleeping for: "+sleepTime+"ms after "+workTime+"ms working");
		if (sleepTime > 0){
			try {
				sleep(sleepTime);
			} catch (Exception e) {}
		}
	}

	private class DrawThread extends Thread{
		@Override
		public void run() {
			while (running) {
				Bitmap currentFrame = framebuffer[drawableBitmap];
				if (!view.getHolder().getSurface().isValid() || view.getHolder().isCreating() || currentFrame == null) {
					continue;
				}
				long startTime = System.currentTimeMillis();
				Canvas c = null;
				try {
					c = view.getHolder().lockCanvas();
					synchronized (view.getHolder()) {
						c.drawBitmap(currentFrame, 0, 0, null);
					}
				} finally {
					if (c != null) {
						view.getHolder().unlockCanvasAndPost(c);
					}
				}
				long endTime = System.currentTimeMillis();
				sleepRemainingFrameTime(GRAFICS_MS_PER_FRAME, endTime-startTime);
			}
		}
	}
}
